/*
 *Copyright (c) 2024 Black Sesame Technologies
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
*/
#include "r5_lsp_crm_func.h"
#include "sw_crm_reg.h"
#include "IntNum.h"


/**
 * @brief return the current core id
 * 
 * @return uint32 0:core0, 1:core1
 */
u32 cpu_get_core_id(void)
{ 
    u32 ret;
    
    asm volatile("MRC p15, 0, %0, c0, c0, 5":"=r"(ret)::"memory");
    return(ret&0x03);
}

/*****************************************************GIC FUNC************************************************************************/
/**
 * @brief Get the int num by reg base object
 * 
 * @param reg_base 
 * @return unsigned int 
 */
unsigned int get_int_num_by_reg_base(unsigned int reg_base)
{
    unsigned int int_num = ISR_NUM_INVALID;

    u32 core_id = cpu_get_core_id();

    switch(reg_base) {
        case WDT0_BASE_ADDR: int_num = SW_INTR_WDT_INTR0;break;
        case WDT1_BASE_ADDR: int_num = SW_INTR_WDT_INTR1;break;
        case WDT2_BASE_ADDR: int_num = SW_INTR_WDT_INTR2;break;
        case WDT3_BASE_ADDR: int_num = SW_INTR_WDT_INTR3;break;
        case WDT4_BASE_ADDR: int_num = SW_INTR_WDT_INTR4;break;
        case WDT5_BASE_ADDR: int_num = SW_INTR_WDT_INTR5;break;

        case MSG_BOX01_ADDR+0x000: return (core_id == 0 ? SW_INTR_MSGBOX_INTR0 : SW_INTR_MSGBOX_INTR4);
        case MSG_BOX01_ADDR+0x200: return (core_id == 0 ? SW_INTR_MSGBOX_INTR1 : SW_INTR_MSGBOX_INTR5);
        case MSG_BOX01_ADDR+0x400: return (core_id == 0 ? SW_INTR_MSGBOX_INTR2 : SW_INTR_MSGBOX_INTR6);
        case MSG_BOX01_ADDR+0x600: return (core_id == 0 ? SW_INTR_MSGBOX_INTR3 : SW_INTR_MSGBOX_INTR7);

        case MSG_BOX23_ADDR+0x000: return (core_id == 0 ? SW_INTR_MSGBOX_INTR0 : SW_INTR_MSGBOX_INTR4);
        case MSG_BOX23_ADDR+0x200: return (core_id == 0 ? SW_INTR_MSGBOX_INTR1 : SW_INTR_MSGBOX_INTR5);
        case MSG_BOX23_ADDR+0x400: return (core_id == 0 ? SW_INTR_MSGBOX_INTR2 : SW_INTR_MSGBOX_INTR6);
        case MSG_BOX23_ADDR+0x600: return (core_id == 0 ? SW_INTR_MSGBOX_INTR3 : SW_INTR_MSGBOX_INTR7);

        case MSG_BOX45_ADDR+0x000: return (core_id == 0 ? SW_INTR_MSGBOX_INTR0 : SW_INTR_MSGBOX_INTR4);
        case MSG_BOX45_ADDR+0x200: return (core_id == 0 ? SW_INTR_MSGBOX_INTR1 : SW_INTR_MSGBOX_INTR5);
        case MSG_BOX45_ADDR+0x400: return (core_id == 0 ? SW_INTR_MSGBOX_INTR2 : SW_INTR_MSGBOX_INTR6);
        case MSG_BOX45_ADDR+0x600: return (core_id == 0 ? SW_INTR_MSGBOX_INTR3 : SW_INTR_MSGBOX_INTR7);
        default: break;
    }
    return(int_num);
}

/**
 * @brief Get the int num by reg base with ch object
 * 
 * @param reg_base 
 * @param ch 
 * @return unsigned int 
 */
unsigned int get_int_num_by_reg_base_with_ch(unsigned int reg_base, unsigned int ch)
{
    unsigned int int_num = ISR_NUM_INVALID;

    if(reg_base == PWM0_BASE_ADDR)
    {
        switch (ch)
        {
        case 0:int_num = SW_INTR_TIMER_INTR0;break;
        case 1:int_num = SW_INTR_TIMER_INTR1;break;
        case 2:int_num = SW_INTR_TIMER_INTR2;break;
        case 3:int_num = SW_INTR_TIMER_INTR3;break;        
        case 4:int_num = SW_INTR_TIMER_INTR4;break;
        case 5:int_num = SW_INTR_TIMER_INTR5;break;
        case 6:int_num = SW_INTR_TIMER_INTR6;break;
        case 7:int_num = SW_INTR_TIMER_INTR7;break;
        default:int_num = ISR_NUM_INVALID;
            break;
        }
    }
    return(int_num);
}

/**
 * @brief Get the addr by int num object
 * 
 * @param int_num 
 * @return unsigned int 
 */
unsigned int get_addr_by_int_num(unsigned int int_num)
{
    unsigned int addr = 0;

    switch (int_num)
    {
        case SW_INTR_TIMER_INTR0:addr = PWM0_BASE_ADDR+0x0C+(0*0x14);break;
        case SW_INTR_TIMER_INTR1:addr = PWM0_BASE_ADDR+0x0C+(1*0x14);break;
        case SW_INTR_TIMER_INTR2:addr = PWM0_BASE_ADDR+0x0C+(2*0x14);break;
        case SW_INTR_TIMER_INTR3:addr = PWM0_BASE_ADDR+0x0C+(3*0x14);break;
        case SW_INTR_TIMER_INTR4:addr = PWM0_BASE_ADDR+0x0C+(4*0x14);break;
        case SW_INTR_TIMER_INTR5:addr = PWM0_BASE_ADDR+0x0C+(5*0x14);break;
        case SW_INTR_TIMER_INTR6:addr = PWM0_BASE_ADDR+0x0C+(6*0x14);break;
        case SW_INTR_TIMER_INTR7:addr = PWM0_BASE_ADDR+0x0C+(7*0x14);break;

        case SW_INTR_MSGBOX_INTR0: addr = 0x000+0x58;break;
        case SW_INTR_MSGBOX_INTR1: addr = 0x200+0x128;break;
        case SW_INTR_MSGBOX_INTR2: addr = 0x400+0x128;break;
        case SW_INTR_MSGBOX_INTR3: addr = 0x600+0x128;break;

        case SW_INTR_MSGBOX_INTR4: addr = 0x000+0x58;break;
        case SW_INTR_MSGBOX_INTR5: addr = 0x200+0x128;break;
        case SW_INTR_MSGBOX_INTR6: addr = 0x400+0x128;break;
        case SW_INTR_MSGBOX_INTR7: addr = 0x600+0x128;break;
        default:
            break;
    }
    return(addr);
}

/*****************************************************SW CRM REGISTERS *********************************************************/
void wdg_reset_mask_ctrl(unsigned int reg_base, unsigned int ctrl)
{
    REG32_WRITE(SW_CRM_ADDR, 0xabcd1234);
    switch (reg_base)
    {
    case WDT0_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_CLEAR32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << 0))): 
                (REG_BIT_SET32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << 0)));
        break;
    case WDT1_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_CLEAR32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 1)))): 
                (REG_BIT_SET32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 1))));
        break;
    case WDT2_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_CLEAR32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 2)))): 
                (REG_BIT_SET32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 2))));
        break;
    case WDT3_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_CLEAR32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 3)))): 
                (REG_BIT_SET32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 3))));
        break;
    case WDT4_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_CLEAR32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 4)))): 
                (REG_BIT_SET32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 4))));
        break;
    case WDT5_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_CLEAR32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 5)))): 
                (REG_BIT_SET32((SW_CRM_ADDR+WDT_RST_MASK_OFFSET), (1 << (0 + 5))));
        break;
    default:
        break;
    }
}


/*****************************************************SW LSP CRM REGISTERS *********************************************************/
void lsp_wdt_sw_reset(unsigned int reg_base)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    switch (reg_base)
    {
    case WDT0_BASE_ADDR:        
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT0_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT0_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    case WDT1_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT1_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT1_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    case WDT2_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT2_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT2_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    case WDT3_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT3_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT3_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    case WDT4_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT4_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT4_WCLK_LOCAL_SW_RST_N_CFG_U32);
    break;
    case WDT5_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT5_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_WDT5_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    default:
        break;
    }
}

void lsp_ray_sw_reset(unsigned int reg_base)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    if (reg_base == FLEXRAY0_BASE_ADDR)
    {
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_RAY0_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_RAY0_WCLK_LOCAL_SW_RST_N_CFG_U32);
    }
    else if (reg_base == FLEXRAY1_BASE_ADDR)
    {
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_RAY1_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_RAY1_WCLK_LOCAL_SW_RST_N_CFG_U32);
    }
}

void lsp_timer_sw_reset(unsigned int reg_base, unsigned int ch)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    switch (reg_base)
    {
    case PWM0_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_TIMER_PCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_TIMER_PCLK_LOCAL_SW_RST_N_CFG_U32);
        if(ch <= 7)
        {
            REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_TIMER0_WCLK_LOCAL_SW_RST_N_CFG_SHIFT_U32 - ch);
            REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_TIMER0_WCLK_LOCAL_SW_RST_N_CFG_SHIFT_U32 - ch);
        }
        break;
    default:
        break;
    }
}

void lsp_lin_sw_reset(unsigned int reg_base)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    switch (reg_base)
    {
    case LIN0_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN0_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN0_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    case LIN1_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN1_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN1_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;   
    case LIN2_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN2_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN2_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    case LIN3_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN3_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN3_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    case LIN4_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN4_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN4_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;
    case LIN5_BASE_ADDR:
        REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN5_WCLK_LOCAL_SW_RST_N_CFG_U32);
        REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LOCAL_RST_CFG_OFFSET), LOCAL_RST_CFG_LSP_LIN5_WCLK_LOCAL_SW_RST_N_CFG_U32);
        break;    
    default:
        break;
    }
}

void lsp_wdt_mode_sel(lsp_ch_cfg_e lsp_ch, lsp_wdt_mode_sel_e mode_sel)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    (mode_sel == LSP_WDT_DW_WDT) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + LSP_SFT_CFG_CTRL_OFFSET), LSP_SFT_CFG_CTRL_WDT_SEL_U32)) :
            (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + LSP_SFT_CFG_CTRL_OFFSET), LSP_SFT_CFG_CTRL_WDT_SEL_U32));
}

unsigned int lsp_ray_stb_state_read(unsigned int reg_base)
{
    unsigned int ret_val = 0;

    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    if(reg_base == FLEXRAY0_BASE_ADDR)
    {
        ret_val = (REG32_READ((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LSP_SFT_CFG_CTRL_OFFSET)) & LSP_SFT_CFG_CTRL_FLEXRAY0_STB_U32) >> LSP_SFT_CFG_CTRL_FLEXRAY0_STB_SHIFT_U32;
    }
    else if(reg_base == FLEXRAY1_BASE_ADDR)
    {
       ret_val = (REG32_READ((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LSP_SFT_CFG_CTRL_OFFSET)) & LSP_SFT_CFG_CTRL_FLEXRAY1_STB_U32) >> LSP_SFT_CFG_CTRL_FLEXRAY1_STB_SHIFT_U32;
    }
    return(ret_val);
}

void lsp_lin_wclk_sel(lsp_ch_cfg_e lsp_ch, lsp_lin_wclk_sel_e wclk_sel)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    (wclk_sel == LSP_LIN_10M) ? (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LSP_SFT_CFG_CTRL_OFFSET), LSP_SFT_CFG_CTRL_LIN_WCLK_SEL_U32)) : 
            (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LSP_SFT_CFG_CTRL_OFFSET), LSP_SFT_CFG_CTRL_LIN_WCLK_SEL_U32));
}

void lsp_lsp_wclk_sel(lsp_ch_cfg_e lsp_ch, lsp_wclk_sel_e wclk_sel)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    (wclk_sel == LSP_WCLK_200M) ? (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LSP_SFT_CFG_CTRL_OFFSET), LSP_SFT_CFG_CTRL_LSP_WCLK_SEL_U32)) : 
            (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR+LSP_SFT_CFG_CTRL_OFFSET), LSP_SFT_CFG_CTRL_LSP_WCLK_SEL_U32));
}

void lsp_parity_cfg_ctrl(lsp_parity_ctrl_e parity, u8 ctrl)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    (ctrl == 0) ? (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + PARITY_CFG_OFFSET), (1 << parity))) :
            (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + PARITY_CFG_OFFSET), (1 << parity)));
}


u8 lsp_parity_status_read(lsp_parity_ctrl_e parity)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    u8 ret_value = 0;
    ret_value = (REG32_READ((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + PARITY_CFG_OFFSET)) >> parity) & 0x01;
    return(ret_value);
}

void lsp_wdt_pause_mode_ctrl(unsigned int reg_base, u8 ctrl)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    switch (reg_base)
    {
    case WDT0_BASE_ADDR:        
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32))) : 
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32)));
        break;
    case WDT1_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 2)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 2))));
        break;
    case WDT2_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 4)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 4))));
        break;
    case WDT3_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 6)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 6))));
        break;
    case WDT4_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 8)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 8))));
        break;
    case WDT5_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 10)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 10))));
        break;
    default:
        break;
    }
}

void lsp_wdt_speed_up_mode_ctrl(unsigned int reg_base, u8 ctrl)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    switch (reg_base)
    {
    case WDT0_BASE_ADDR:        
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 1)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 1))));
        break;
    case WDT1_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 3)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 3))));
        break;
    case WDT2_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 5)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 5))));
        break;
    case WDT3_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 7)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 7))));
        break;
    case WDT4_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 9)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 9))));
        break;
    case WDT5_BASE_ADDR:
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 11)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (LSP_SFT_CFG_CTRL_WDT_SFT_CFG_CTRL_SHIFT_U32 + 11))));
        break;
    default:
        break;
    }
}

void lsp_timer_pause_mode_ctrl(unsigned int reg_base, unsigned int ch, u8 ctrl)
{
    REG32_WRITE(SWT_LSP_CRM_REG_CTRL_BASE_ADDR+0x224, 0xABCD1234);
    if(reg_base == PWM0_BASE_ADDR && ch < 8)
    {
        (ctrl == 1) ? (REG_BIT_SET32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (TIMER_SFT_CFG_CTRL_TIMER_SFT_CFG_CTRL_SHIFT_U32 + ch)))) :
                (REG_BIT_CLEAR32((SWT_LSP_CRM_REG_CTRL_BASE_ADDR + TIMER_SFT_CFG_CTRL_OFFSET), (1 << (TIMER_SFT_CFG_CTRL_TIMER_SFT_CFG_CTRL_SHIFT_U32 + ch))));
    }
}